package com.custom.spring.start.shiro;

import net.sf.ehcache.CacheManager;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.type.AnnotationMetadata;

/**
 * ClassName: EnableShiroConfig
 * Description:
 *
 * @author kang.wang03
 *         Date 16/5/25
 */
@Configuration
@EnableConfigurationProperties(ShiroConfig.class)
public class EnableShiroConfig implements ImportAware, BeanClassLoaderAware {
    @Autowired(required = false)
    private ShiroConfig shiroConfig;
    @Bean(
            name = {"com.custom.spring.start.shiro.ShiroConfig"}
    )
    @ConditionalOnMissingBean
    public ShiroConfig shiroConfig() {
        return new ShiroConfig();
    }
    @Bean(
            name = {"org.apache.shiro.realm.authorizingRealm"}
    )
    @ConditionalOnMissingBean
    public AuthorizingRealm authorizingRealm(){
        return new AuthorizingRealm() {
            @Override
            protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
                return null;
            }

            @Override
            protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
                return null;
            }
        };
    }
    @Bean(
            name = {"net.sf.ehcache.CacheManager"}
    )
    @ConditionalOnMissingBean
    public CacheManager cacheManager(){
        return new CacheManager();
    }
    @Bean
    @ConditionalOnMissingBean
    public EhCacheManager ehCacheManagerBean(net.sf.ehcache.CacheManager cacheManager) {
        EhCacheManager ehCacheManager = new EhCacheManager();
        ehCacheManager.setCacheManager(cacheManager);
        return ehCacheManager;
    }

    @Bean
    @ConditionalOnMissingBean
    public DefaultWebSecurityManager defaultWebSecurityManager(EhCacheManager ehCacheManager, AuthorizingRealm authorizingRealm) {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setCacheManager(ehCacheManager);
        defaultWebSecurityManager.setRealm(authorizingRealm);
        return defaultWebSecurityManager;
    }

    @Bean
    @ConditionalOnMissingBean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager, String shiroFilterChainDefinitions) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        shiroFilterFactoryBean.setFilterChainDefinitions(shiroFilterChainDefinitions);
        shiroFilterFactoryBean.setLoginUrl(shiroConfig.getLoginUrl());
        return shiroFilterFactoryBean;
    }

    @Bean
    @ConditionalOnMissingBean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {

    }

    @Override
    public void setImportMetadata(AnnotationMetadata importMetadata) {

    }
}
